package com.gzhu.knowledgeAdmin.service.impl;


import com.gzhu.knowledgeAdmin.common.exception.BusinessException;
import com.gzhu.knowledgeAdmin.common.result.ErrorCode;
import com.gzhu.knowledgeAdmin.common.result.TreeNode;
import com.gzhu.knowledgeAdmin.common.utils.UserInfoUtils;
import com.gzhu.knowledgeAdmin.common.vo.TemplateVO;
import com.gzhu.knowledgeAdmin.entity.AnswerType;
import com.gzhu.knowledgeAdmin.entity.Flow;
import com.gzhu.knowledgeAdmin.entity.Template;
import com.gzhu.knowledgeAdmin.parammanage.RecorderCache;
import com.gzhu.knowledgeAdmin.repository.AnswerTypeRepository;
import com.gzhu.knowledgeAdmin.repository.FlowRepository;
import com.gzhu.knowledgeAdmin.service.FlowService;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class FlowServiceImpl implements FlowService {

    @Resource
    private AnswerTypeRepository answerTypeRepository;

    @Resource
    private FlowRepository flowRepository;

    @Resource
    private RecorderCache recorderCache;

    @Override
    public List<String> getAnswerType() {
        List<AnswerType> answerTypeList = answerTypeRepository.findAll();
        List<String> typeList = answerTypeList.stream().map(answerType -> answerType.getName()).collect(Collectors.toList());
        return typeList;
    }

    @Override
    public List<Flow> getFlowByTemplateId(int templateId) {

        return flowRepository.getByTemplateId(templateId);
    }

    @Override
    public int getTargetId(int templateId, String answerType) {
        Flow nextFlow = flowRepository.getByTemplateIdAndAnswerType(templateId, answerType);
        if (nextFlow == null) {
            throw new BusinessException(ErrorCode.NOT_FOUND_ERROR,"请求数据不存在");
        }
        return nextFlow.getAnswerTarget();
    }

    @Override
    public List<String> getHasAnswerTypeById(int templateId) {
        List<Flow> flowList = flowRepository.getByTemplateId(templateId);
        ArrayList<String> list = new ArrayList<>();
        for (Flow flow : flowList) {
            String answerType = flow.getAnswerType();
            String[] strings = answerType.split(",");
            list.addAll(Arrays.asList(strings));
        }
//        return flowList.stream().map(Flow::getAnswerType).collect(Collectors.toList());
        return list;
    }

    @Override
    public int UpdateLogicOrderOnInsertBW(String name, int afterId) {
        List<Integer> templateIds = getMeAndChildTemplateId(name, afterId);
        //要对after后的逻辑顺序进行修改
        int result = flowRepository.updateLogicOrderByTemplateIds(templateIds);
        return result;
    }

    /**
     * 根据name,和id,获取到该话术和根在该话术后的节点的id
     * @param name
     * @param myId
     * @return
     */
    @Override
    public List<Integer> getMeAndChildTemplateId(String name,int myId){
//        List<Flow> flowList = flowRepository.getByName(name);

        // 整合-获取公司id
        String gsid = UserInfoUtils.getCurrentUser().getGsid();
        List<Flow> flowList = flowRepository.getFlowByNameAndGSID(name, gsid);
//        List<Flow> flowList = flowRepository.getFlowByNameAndGSID(name, UserInfoUtil.getCurrentUser().getUser().getF_GSID());
        //先找出根节点
        int rootId = getRootId(flowList);
        //构造出templateId和answerTarget的map映射
        HashMap<Integer, List<Integer>> map = getIdAndTargetMapByFlowList(flowList);
        //构造树结构
        TreeNode rootNode = buildTree(rootId,map);
        //获取要修改理解顺序的节点(此处包括最后面的尾节点的templateId,但不影响修改flow)
        List<Integer> templateIds = getChildrenById(rootNode, myId);
        return templateIds;
    }

    /**
     * 根据flowList,得出templateId和target的一个映射关系,一个templateId可能对应多个target
     * @param flowList
     * @return
     */
    @Override
    public HashMap<Integer, List<Integer>> getIdAndTargetMapByFlowList(List<Flow> flowList){
        HashMap<Integer, List<Integer>> map = new HashMap<>();
        for (Flow flow : flowList) {
            Integer templateId = flow.getTemplateId();
            Integer answerTarget = flow.getAnswerTarget();
            if (!map.containsKey(templateId)) {
                ArrayList<Integer> list = new ArrayList<>();
                list.add(answerTarget);
                map.put(templateId,list);
            }else {
                List<Integer> list = map.get(templateId);
                list.add(answerTarget);
            }
        }
        return map;
    }

    /**
     * 根据id,获取到该id和该id后的结点
     * @param root
     * @param id
     * @return 返回节点集合
     */
    @Override
    public List<Integer> getChildrenById(TreeNode root, int id){
        TreeNode node = getNodeById(root, id);

        List<Integer> ids = getChild(node);

        return ids;
    }
    //handler
    private List<Integer> getChild(TreeNode node){
        List<Integer> list = new ArrayList<>();
        //把本身的id加进去
        list.add(node.getId());
        //在获取children的id
        List<TreeNode> children = node.getChildren();
        if (children != null) {
            for (TreeNode childNode : children) {
                List<Integer> childIds = getChild(childNode);
                list.addAll(childIds);
            }
        }
        return list;
    }

    /**
     * 根据id,在树结构中,对应的id的TreeNode
     * @param root 根节点
     * @param id 要找到节点的id
     * @return TreeNode
     */
    private TreeNode getNodeById(TreeNode root, int id){
        if (root.getId() == id) {
            return root;
        }
        List<TreeNode> children = root.getChildren();
        if (children != null) {
            for (TreeNode child : children) {
                TreeNode node = getNodeById(child, id);
                if (node != null) {
                    return node;
                }
            }
        }
        return null;
    }

    /**
     * 递归,建造树型结构
     * @param rootId
     * @param map
     * @return 返回根节点
     */
    @Override
    public TreeNode buildTree(int rootId, HashMap<Integer, List<Integer>> map) {
        List<Integer> rootList = map.get(rootId);
        List<TreeNode> childrenList = null;
        if (rootList != null) {
            childrenList = new ArrayList<>();
            for (Integer nextRoot : rootList) {
                TreeNode treeNode = buildTree(nextRoot, map);
                childrenList.add(treeNode);
            }
        }
        TreeNode treeNode = new TreeNode(rootId, childrenList);
        //TO DO 填充template信息 不能一条一条信息从数据库获取
//        Optional<Template> templateOptional = templateRepository.findById(rootId);
//        if (templateOptional.isPresent()){
//            Template template = templateOptional.get();
//            treeNode.setTemplate(template);
//        }
        return treeNode;
    }

    /**
     * 递归,建造树型结构
     * @param rootId
     * @param map
     * @return 返回根节点
     */
    @Override
    public TreeNode buildTree(int rootId, HashMap<Integer, List<Integer>> map, HashMap<Integer, Template> allTemplateMap, List<Flow> flowList) {
        //获取根节点 下 子节点的集合
        List<Integer> rootList = map.get(rootId);
        List<TreeNode> childrenList = null;
        if (rootList != null) {
            childrenList = new ArrayList<>();
            for (Integer nextRoot : rootList) {
                TreeNode treeNode = buildTree(nextRoot, map,allTemplateMap,flowList);
                childrenList.add(treeNode);
            }
        }
        TemplateVO templateVO = new TemplateVO();
        Template template = allTemplateMap.get(rootId);
        BeanUtils.copyProperties(template,templateVO);
        templateVO.setAnswerType(new ArrayList<>());
        //设置公司id
        templateVO.setGsid(template.getGsid());
        templateVO.setAiId(recorderCache.getAiIdByRecorderName(templateVO.getRecorder()));
        for (Flow flow : flowList) {
            if (flow.getAnswerTarget() == rootId) {
                //TO DO 填充flow的信息
//                templateVO.setAnswerType(flow.getAnswerType());
                //处理answerType,以list形式返回
                String[] strings = flow.getAnswerType().split(",");
                ArrayList<String> answerTypeList = new ArrayList<>(Arrays.asList(strings));
                templateVO.setAnswerType(answerTypeList);
                templateVO.setLogicName(flow.getLogicName());
                templateVO.setLogicOrder(flow.getLogicOrder());
                break;
            }
        }

        return new TreeNode(rootId,templateVO, childrenList);
    }

    /**
     * 根据flowList,找出根节点,也就是开场白
     * 在answerTarget中没有的,templateId中有的就是root
     * @param flowList
     * @return 开始节点id
     */
    private int getRootId(List<Flow> flowList){
        HashMap<Integer, Integer> map = new HashMap<>();
        for (Flow flow : flowList) {
            Integer templateId = flow.getTemplateId();
            map.put(templateId,1);
        }
        for (Flow flow : flowList) {
            Integer answerTarget = flow.getAnswerTarget();
            if (map.containsKey(answerTarget)) {
                map.put(answerTarget,map.get(answerTarget) + 1);
            }
        }
        int rootId = 0;
        for (Integer key : map.keySet()) {
            if (map.get(key) == 1) {
                rootId = key;
                break;
            }
        }
        return rootId;
    }

//    @Data
//    @AllArgsConstructor
//    class TreeNode {
//        Integer id;//我的id
//        List<TreeNode> children;//子id
//    }
}
